package com.wanglei.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanglei.constants.SystemConstants;
import com.wanglei.domain.ResponseResult;
import com.wanglei.domain.entity.Menu;
import com.wanglei.domain.entity.RoleMenu;
import com.wanglei.domain.vo.MenuVVo;
import com.wanglei.domain.vo.MenuVo;
import com.wanglei.domain.vo.RolePageVo;
import com.wanglei.mapper.RoleMenuMapper;
import com.wanglei.service.MenuService;
import com.wanglei.mapper.MenuMapper;
import com.wanglei.utils.BeanCopyUtils;
import com.wanglei.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author MrWang
* @description 针对表【sys_menu(菜单权限表)】的数据库操作Service实现
* @createDate 2023-07-03 13:48:28
*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
    implements MenuService{

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    //查看用户权限列表
    @Override
    public List<String> selectPermsByUserId(Long id) {
        //如果是管理员，返回所有的权限
        if(id==1){
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<Menu>()
                    .eq(Menu::getStatus,SystemConstants.Menu_STATUS_NORMAL)
                    .in(Menu::getMenuType,"C","F");
            List<Menu> menus = menuMapper.selectList(queryWrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        //否则返回所具有的权限
        return menuMapper.selectPermsByUserId(id);
    }

    //返回多级菜单
    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        List<Menu> menus = null;
        if (SecurityUtils.isAdmin()){//超级管理员 获取所有菜单
            menus = menuMapper.selectAllRouterMenu();
        }else {//其他用户 获取对应userid的菜单
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<Menu> menusTree = builderMenuTree(menus,0L);
        return menusTree;
    }

    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                //注意:这里的set没有返回值 需要在Menu实体类上加@Accessors(chain = true)
                //chain = true的作用是使成员属性的set方法不再返回void，而是返回对象本身，从而实现链式赋值
                .map(menu -> menu.setChildren(getChildren(menu,menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    //递归
    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m -> m.setChildren(getChildren(m,menus)))// set同上
                .collect(Collectors.toList());
        return childrenList;
    }

    //参加所有菜单列表
    @Override
    public ResponseResult menuList() {
        List<Menu> menus = menuMapper.selectList(null);
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus, MenuVo.class);
        return ResponseResult.okResult(menuVos);
    }

    //新增菜单
    @Override
    public ResponseResult addMenu(Menu menu) {
        menuMapper.insert(menu);
        return ResponseResult.okResult();
    }

    //查看菜单详情
    @Override
    public ResponseResult getMenuDetailById(Long id) {
        Menu menu = menuMapper.selectById(id);
        MenuVo menuVo = BeanCopyUtils.copyBean(menu, MenuVo.class);
        return ResponseResult.okResult(menuVo);
    }

    //修改菜单信息
    @Override
    public ResponseResult updateMenu(Menu menu) {
        menuMapper.updateById(menu);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteMenu(Long id) {
        //删除菜单
        menuMapper.deleteById(id);
        //删除菜单和角色的关联信息
        roleMenuMapper.deleteByMenuId(id);
        return ResponseResult.okResult();
    }

    //新增角色 需要提前获取菜单树信息
    @Override
    public ResponseResult treeselect() {
        List<MenuVVo> menus = menuMapper.treeselect();
        menus.stream() //给label赋值 就是menuName的值
                .map(menuVVo -> menuVVo.setLabel(menuVVo.getMenuName()))
                .collect(Collectors.toList());
        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<MenuVVo> menusTree = builderMenuTree2(menus,0L);
        System.out.println("111111111111111"+menus);
        return ResponseResult.okResult(menusTree);
    }

    private List<MenuVVo> builderMenuTree2(List<MenuVVo> menus, Long parentId) {
        List<MenuVVo> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                //注意:这里的set没有返回值 需要在Menu实体类上加@Accessors(chain = true)
                //chain = true的作用是使成员属性的set方法不再返回void，而是返回对象本身，从而实现链式赋值
                .map(menu -> menu.setChildren(getChildren2(menu,menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    private List<MenuVVo> getChildren2(MenuVVo menu, List<MenuVVo> menus) {
        List<MenuVVo> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m -> m.setChildren(getChildren2(m,menus)))// set同上
                .collect(Collectors.toList());
        return childrenList;
    }

    //加载对应角色菜单列表树接口 。
    //menus：菜单树 checkedKeys：角色所关联的菜单权限id列表。
    @Override
    public ResponseResult roleMenuTreeselect(Long id) {
        //菜单树
        if (id==1){//超级管理员 拥有所有菜单权限
            List<String> checkedKeys = new ArrayList<>();
            checkedKeys.add("admin");
            return ResponseResult.okResult(new RolePageVo((List<MenuVVo>)treeselect().getData(),checkedKeys));
        }
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<RoleMenu>()
                .eq(RoleMenu::getRoleId,id);
        List<RoleMenu> roleMenus = roleMenuMapper.selectList(queryWrapper);

        //角色所关联的菜单权限id列表
        List<String> menuIds = roleMenus.stream()
                .map(roleMenu -> String.valueOf(roleMenu.getMenuId()))
                .collect(Collectors.toList());
        System.out.println(id+"   1111111111111111111"+menuIds);

        List<MenuVVo> menuVVos = new ArrayList<>();//roleId 对应的权限列表
        for (int i = 0; i < menuIds.size(); i++) {
            Menu menu = menuMapper.selectById(Long.valueOf(menuIds.get(i)));
            MenuVVo menuVVo = BeanCopyUtils.copyBean(menu, MenuVVo.class);
            menuVVo.setLabel(menuVVo.getMenuName());
            menuVVos.add(menuVVo);
        }
        System.out.println("222222222222222222"+menuVVos);
        List<MenuVVo> menusTree = builderMenuTree2(menuVVos,0L);//对应的权限菜单树

        return ResponseResult.okResult(new RolePageVo(menusTree,menuIds));
    }
}




